/** @file bitmap.h
    @brief Bitmap operations */

#ifndef G3_BITMAP_H
#define G3_BITMAP_H

#include "types.h"
#include "color.h"
#include "log.h"

#include <boost/shared_ptr.hpp>

// OpenGL compatible bitmap types
#ifndef GL_RGB
#define GL_RGB      0x1907
#endif

#ifndef GL_RGBA
#define GL_RGBA     0x1908
#endif

#ifndef GL_BGR
#define GL_BGR      0x80E0
#endif

#ifndef GL_BGRA
#define GL_BGRA     0x80E1
#endif

/** Bitmap data is compressed */
#define BITMAP_COMPRESSED		1
/** Bitmap data is grayscale */
#define BITMAP_GRAYSCALE		2
/** Bitmap data is RGBA */
#define BITMAP_RGBA				4
/** Bitmap has nonstandard bit alignment */
#define BITMAP_ALIGNMENT		8

namespace G3 {

/** @class BITMAP
    @brief The bitmap class */
class BITMAP {
	public:
        /**
            @brief A constructor
        */
		BITMAP ();
        /**
            @brief A destructor
        */
		~BITMAP ();

        /** Bitmap width */
		ushort Width;
		/** Bitmap height */
		ushort Height;
		/** Bitmap color depth */
		byte BitsPerPixel;
		/** Data bit alignment */
		byte PackedAlignment;

        /** Data compression */
		uint Compression;
		/** Number of precalculated mipmaps */
		byte NumMipMaps;

        /** Size of the data block */
		long Size;

        /** Pointer to the data block */
		byte *Data;

        /** Bitmap flags */
		byte Flags;

        /** Pointer to the log */
		G3::LOG *Log;

        /**
            @brief Assignment operator
            @param[in] b Reference to the other bitmap to be copied
            @return Reference to the freshly copied bitmap
        */
		BITMAP& operator=(const BITMAP &b);

        /**
            @brief Allocates memory for a bitmap
            @param[in] Width Bitmap width
            @param[in] Height Bitmap height
            @param[in] ColorDepth Bitmap color depth (in bits)
            @return True on success, otherwise false
        */
		bool Create (int Width, int Height, int ColorDepth);

        /**
            @brief Sets a pixel
            @param[in] x Pixel x-coordinate
            @param[in] y Pixel y-coordinate
            @param[in] col Pixel color
        */
		void SetPixel (uint x, uint y, COL4B col);

        /**
            @brief Gets a pixel
            @param[in] x Pixel x-coordinate
            @param[in] y Pixel y-coordinate
            @return The color of the pixel
        */
		COL4B GetPixel (uint x, uint y);

        /**
            @brief Checks if the bitmap data is valid
            @return True if it is, false otherwise
        */
		bool IsValid ();

        /**
            @brief Clears the bitmap (fills with black pixels)
        */
		void Clear ();

        /**
            @brief Destroys the bitmap
        */
		void Destroy ();
};

/**
    @brief Draws a rectangle outline onto the bitmap
    @param[out] bmp Pointer to the bitmap
    @param[in] x1 X-coordinate of the upper left corner
    @param[in] y1 Y-coordinate of the upper left corner
    @param[in] x2 X-coordinate of the lower right corner
    @param[in] y2 Y-coordinate of the lower right corner
    @param[in] col Rectangle color
    @return True on success, false on failure
*/
bool DrawRect (BITMAP *bmp, uint x1, uint y1, uint x2, uint y2, COL4F col);

/**
    @brief Draws a filled rectangle onto the bitmap
    @param[out] bmp Pointer to the bitmap
    @param[in] x1 X-coordinate of the upper left corner
    @param[in] y1 Y-coordinate of the upper left corner
    @param[in] x2 X-coordinate of the lower right corner
    @param[in] y2 Y-coordinate of the lower right corner
    @param[in] col Rectangle color
    @return True on success, false on failure
*/
bool DrawRectFill (BITMAP *bmp, uint x1, uint y1, uint x2, uint y2, COL4F col);

/**
    @brief Flips the bitmap vertically
    @param[out] bmp Pointer to the bitmap to be flipped
    @return True on success, false on failure
*/
bool FlipVertical (BITMAP *bmp);

/**
    @brief Flips the bitmap horizontally
    @param[out] bmp Pointer to the bitmap to be flipped
    @return True on success, false on failure
*/
bool FlipHorizontal (BITMAP *bmp);

/**
    @brief Blits a region of one bitmap onto another bitmap
    @param[in] Src Pointer to the source bitmap
    @param[in] Dest Pointer to the destination bitmap
    @param[in] x1 X-coordinate of the upper left corner on the source bitmap
    @param[in] y1 Y-coordinate of the upper left corner on the source bitmap
    @param[in] x2 X-coordinate of the upper left corner on the destination bitmap
    @param[in] y2 Y-coordinate of the upper left corner on the destination bitmap
    @param[in] w Width of the region
    @param[in] h Height of the region
    @param[in] col Rectangle color
    @return True on success, false on failure
*/
bool BlitBitmap (BITMAP *Src, BITMAP *Dest, uint x1, uint y1, uint x2, uint y2, uint w, uint h);

/**
    @brief Crops the bitmap to power of 2 dimensions
    @param[out] bmp Pointer to the bitmap to be cropped
    @return True on success, false on failure
*/
bool MakePow2 (BITMAP *bmp);

}

#endif //G3_BITMAP_H
